<template>
  <div>
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span>文章列表</span>
      </div>
      <!-- 搜索区域 -->
      <div class="search-box">
        <el-form :inline="true" :model="filter">
          <el-form-item label="文章分类">
            <el-select v-model="filter.cate_id" placeholder="请选择分类" size="small">
              <!-- <el-option label="区域一" value="shanghai"></el-option> -->
              <el-option :label="item.cate_name" :value="item.id" v-for="item in cateList" :key="item.id"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="发布状态" style="margin-left: 15px;">
            <el-select v-model="filter.state" placeholder="请选择状态" size="small">
              <el-option label="已发布" value="已发布"></el-option>
              <el-option label="草稿" value="草稿"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" size="small" @click="search">筛选</el-button>
            <el-button type="info" size="small" @click="resetSearch">重置</el-button>
          </el-form-item>
        </el-form>
        <!-- 发表文章的按钮 -->
        <el-button type="primary" size="small" class="btn-pub" @click="addArtVisible = true">发表文章</el-button>
      </div>

      <!-- 文章表格区域 -->
      <!-- 文章表格区域 -->
      <el-table :data="artList" style="width: 100%;" border stripe>
        <el-table-column label="文章标题" prop="title">
          <template v-slot="scope">
             <el-link type="primary" @click="getArtDetail(scope.row.id)">{{ scope.row.title }}</el-link>
          </template>
        </el-table-column>
        <el-table-column label="分类" prop="cate_name"></el-table-column>
        <el-table-column label="发表时间">
          <template v-slot="scope">
            <!-- {{ scope.row.pub_date }} -->
            {{ formatDate(scope.row.pub_date) }}
          </template>
        </el-table-column>
        <el-table-column label="状态" prop="state"></el-table-column>
        <el-table-column label="操作">
          <template v-slot="scope">
            <el-button size="mini" type="danger" @click="del(scope.row.id)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页区域 -->
      <!-- current-page 当前的页码值 -->
      <!-- page-size 每一页显示多少条数据 -->
      <!-- total: 文章列表 总共有多少条数据 -->
      <!-- @current-change 当页码值发生改变时触发 -->
      <!-- @size-change 当每一页显示多少条数据 发生改变时 触发 -->
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="q.pagenum"
        :page-sizes="[2, 5, 10, 20]"
        :page-size="q.pagesize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total">
      </el-pagination>
    </el-card>

    <!-- 发表文章的对话框 -->
    <el-dialog
      title="发表文章"
      :visible.sync="addArtVisible"
      fullscreen
      @closed="onClose"
      :before-close="handleClose">
      <!-- 表单 -->
      <!-- 发布文章的表单 -->
      <!-- model 关联表单的数据对象 -->
      <!-- rules 定义表单的数据校验对象 -->
      <el-form :model="pubForm" :rules="pubFormRules" ref="pubFormRef" label-width="100px">
        <el-form-item label="文章标题" prop="title">
          <el-input v-model="pubForm.title" placeholder="请输入标题"></el-input>
        </el-form-item>
        <el-form-item label="文章分类" prop="cate_id">
          <el-select v-model="pubForm.cate_id" placeholder="请选择分类" style="width: 100%;">
            <!-- <el-option label="区域一" value="shanghai"></el-option> -->
            <!-- label 属性 是给 用户看的信息 -->
            <!-- value 用于给服务器的数据 -->
            <el-option :label="item.cate_name" :value="item.id" v-for="item in cateList" :key="item.id"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="文章内容" prop="content">
           <quill-editor v-model="pubForm.content" @blur="$refs.pubFormRef.validateField('content')">
           </quill-editor>
        </el-form-item>
        <el-form-item label="文章封面" prop="cover_img">
          <!-- 用来显示封面的图片 -->
          <img v-if="preview" :src="preview" alt="" class="cover-img" ref="imgRef" />
          <img v-else src="../../../assets/images/cover.jpg" alt="" class="cover-img" ref="imgRef" />
          <br />
          <!-- 文件选择框，默认被隐藏 -->
          <input type="file" style="display: none;" accept="image/*" ref="iptFile" @change="cImage" />
          <!-- 选择封面的按钮 -->
          <el-button type="text" @click="$refs.iptFile.click()">+ 选择封面</el-button>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="add('已发布')">发布</el-button>
          <el-button type="info" @click="add('草稿')">存为草稿</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>

    <!-- 显示文章详情 -->
    <!-- 查看文章详情的对话框 -->
      <el-dialog title="文章预览" :visible.sync="detailVisible" width="80%">
        <h1 class="title">{{ artInfo.title }}</h1>

        <div class="info">
          <span>作者：{{ artInfo.nickname || artInfo.username }}</span>
          <span>发布时间：{{ formatDate(artInfo.pub_date) }}</span>
          <span>所属分类：{{ artInfo.cate_name }}</span>
          <span>状态：{{ artInfo.state }}</span>
        </div>
        
        <!-- 分割线 -->
        <el-divider></el-divider>

        <img :src="'http://big-event-vue-api-t.itheima.net' + artInfo.cover_img" alt="" />

        <div v-html="artInfo.content"></div>
      </el-dialog>

  </div>
</template>

<script>
// 引入 dayjs 
import dayjs from 'dayjs'
export default {
  name: 'ArtList',
  data() {
    return {
      // 查询参数对象
      q: {
        pagenum: 1, // 页码
        pagesize: 2, // 每一页显示多少条数据
        cate_id: '',
        state: ''
      },
      // 控制 发表文章对话框的显示与隐藏
      addArtVisible: false,
      // 表单文章的数据对象
      pubForm: {
        title: '',
        cate_id: '',
        content: '',
        cover_img: '',
        state: ''
      },
      // 发表文章的表单的校验对象
      pubFormRules: {
         title: [
          { required: true, message: '请输入文章标题', trigger: 'blur' },
          { min: 1, max: 30, message: '文章标题的长度为1-30个字符', trigger: 'blur' }
        ],
        cate_id: [{ required: true, message: '请选择文章分类', trigger: 'click' }],
        content: [{ required: true, message: '请输入文章内容', trigger: 'blur' }],
        cover_img: [{ required: true, message: '请选择图片', trigger: 'click' }],
      },
      // 文章分类的数据
      cateList: [],
      preview: '', // 用于保存图片的url 地址
      // 文章列表
      artList: [],
      // 保存 文章列表的总条数
      total: 0,
      // 专用于 筛选
      filter: {
        cate_id: '',
        state: ''
      },
      artInfo: {},
      detailVisible: false
    }
  },
  methods: {
    handleClose(done) {
      this.$confirm('此操作将永久关闭, 是否继续?', '提示', {
        type: 'warning'
      })
        .then(_ => {
          done();
        })
        .catch(_ => {});
    },
    // 获取所有的文章分类
    async getArtCate() {
      const { data: res } =  await this.$http({
          method: 'get',
          url: '/my/cate/list'
      })
    //  console.log(res)
      // 获取失败
      if (res.code !== 0) return this.$message.error(res.message)
      // 获取成功
      this.cateList = res.data
    },
    cImage(e) {
      // 选择图片
      // console.dir(e)
      const file = e.target.files[0]
      // console.log(file)
      if (file) {
        // 表示选择了图片
        // console.log('表示选择了图片');
        // 选择了图片 将图片的信息 保存到 pubForm.cover_img 属性里面
        // console.log(file)
        this.pubForm.cover_img = file
        // img 标签 支持 url | BASE64格式的字符串
        this.preview = URL.createObjectURL(file)

      } else {
        // 表示没有选择图片
        // console.log('表示没有选择图片')
        this.pubForm.cover_img = ''
        this.preview = ''
      }
      this.$refs.pubFormRef.validateField('cover_img')
    },
    // 发表文章
    add(state) {
      // console.log(state)
      this.pubForm.state = state
      // 1. 对表单进行兜底校验
      this.$refs.pubFormRef.validate( async valid => {
        if (!valid) return
        // 2. 表单数据合法 
        const fd = new FormData()

        // 可以使用 for..in 语法 遍历 this.pubForm 对象
        for(let k in this.pubForm) {
          fd.append(k, this.pubForm[k])
        }

        const { data: res } = await this.$http({
          method: 'post',
          url: '/my/article/add',
          data: fd
        })

        if (res.code !== 0) return this.$message.error(res.message)
        this.$message.success(res.message)
        // 关闭对话框
        this.addArtVisible = false
        // 重新获取 文章列表
        this.getArtList()
      })
    },
    // 关闭对话框时 需要将 pubForm 里面的数据清空
    onClose() {
      // 将表单里面的数据清空
      this.pubForm = {
        title: '',
        cate_id: '',
        content: '',
        cover_img: '',
        state: ''
      }
      // 将预览图片清空
      this.preview = ''
    },
    // 获取文章列表数据
    async getArtList() {
      const { data: res } = await this.$http({
        method: 'get',
        url: '/my/article/list',
        params: {
          ...this.q
        }
      })
      if (res.code !== 0) return this.$message.error(res.message)
      // console.log(res)
      this.artList = res.data
      this.total = res.total
    },
    // 用于格式化时间
    formatDate(val) {
      return dayjs(val).format('YYYY-MM-DD HH:mm:ss')
    },
    handleSizeChange(size) {
      // console.log(size)
      this.q.pagesize = size
      // 再次调用 获取文章列表的数据
      this.getArtList()
    },
    handleCurrentChange(pNum) {
      // console.log(pNum)
      // 获取当前的页码值
      this.q.pagenum = pNum
      // 再次调用 
      this.getArtList()
    },
    search() {
      this.q.cate_id = this.filter.cate_id
      this.q.state = this.filter.state
      this.q.pagenum = 1
      // console.log(this.q)
      this.getArtList()
    },
    resetSearch() {
      // 将 filter 里面的数据 清空
      this.filter = {
        cate_id: '',
        state: ''
      }
      this.q = {
        state: '',
        cate_id: '',
        pagenum: 1,
        pagesize: 2
      }
    },
    del(id) {
      this.$confirm('此操作将永久删除该文章, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        // 需要向服务器 发送ajax 
        const { data: res } = await  this.$http({
          url: '/my/article/info',
          method: 'delete',
          params: {
            id: id
          }
        })
        // 删除失败
        if (res.code !== 0) return this.$message.error(res.message)
        // 删除成功
        this.$message.success(res.message)

        // 如果 artList 数组里面 只有 1 条数据  并且 不是在第一页  回到上一页
        if (this.artList.length === 1 && this.q.pagenum > 1) {
          this.q.pagenum--
        }

        // 重新获取数据
        this.getArtList()
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });          
      });
    },
    async getArtDetail(id) {
      // 根据id 获取文章详情数据
      const { data: res } = await this.$http({
        url: '/my/article/info',
        params: {
          id
        }
      })
      // 获取失败
      if (res.code !== 0) return this.$message.error(res.message)
      // 获取成功
      this.artInfo = res.data
      // 将 文章详情的 对话框 显示出来
      this.detailVisible = true

    }
  },
  created() {
    // 获取文章分类
    this.getArtCate()
    // 获取文章列表
    this.getArtList()
  }
}
</script>

<style lang="less" scoped>

// scoped 属性的作用：
// 1. 给 当前组件的 template 里面的标签 添加 自定义属性  data-v-hash值
// 2. 给 当前 sytle 标签里面的   css 选择器[data-v-hash]
// 3. 如果 template 标签里面 有 组件 只会给 组件的根标签 添加 data-v-hash值


// /deep/ 深度选择器 作用： 将 交集选择器 变成 后代选择器 
// css选择器[data-v-hash]  [data-v-hash] css选择器


.search-box {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  .btn-pub {
    margin-top: 5px;
  }
}
/deep/ .ql-editor {
  height: 300px;
}

// 设置图片封面的宽高
.cover-img {
  width: 400px;
  height: 280px;
  object-fit: cover;
}
.el-pagination {
  margin-top: 15px;
}
.title {
  font-size: 24px;
  text-align: center;
  font-weight: normal;
  color: #000;
  margin: 0 0 10px 0;
}

.info {
  font-size: 12px;
  span {
    margin-right: 20px;
  }
}
</style>
